package com.gp.library.utils;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.PowerManager;

import java.util.HashMap;

/**
 * Created by jackdeng on 2021/4/13.
 */

public class WakeLockUtils {

    private static final String TAG_DEFAULT = "WakeLockUtils";

    private HashMap<String, PowerManager.WakeLock> locks = new HashMap<>();

    private static final int TIMEOUT_DEFAULT = -1;

    private static Context mContext;

    private PowerManager.WakeLock mLock;
    private boolean mLockToCreate;

    private static WakeLockUtils INSTANCE = null;

    private WakeLockUtils() {
    }

    public static WakeLockUtils getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new WakeLockUtils();
        }

        return INSTANCE;
    }

    public void init(Context context) {
        mContext = context;
    }

    public void createWakeLock() {
        createWakeLock(TAG_DEFAULT, TIMEOUT_DEFAULT);
    }

    public void createWakeLock(String tag) {
        createWakeLock(tag, TIMEOUT_DEFAULT);
    }

    public void createWakeLock(long timeout) {
        createWakeLock(TAG_DEFAULT, timeout);
    }

    @SuppressLint("InvalidWakeLockTag")
    public void createWakeLock(String tag, long timeout) {
        if (mLockToCreate) {
            synchronized (this) {
                if (mLockToCreate) {
                    mLockToCreate = false;
                    if (mContext != null) {
                        mLock = ((PowerManager) mContext.getSystemService(Context.POWER_SERVICE)).newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, tag);
                        if (timeout == TIMEOUT_DEFAULT) {
                            mLock.acquire();
                        } else {
                            mLock.acquire(timeout);
                        }
                    } else {
                        LogUtils.d(TAG_DEFAULT, "WakeLockUtils not init with context");
                    }
                }
            }
        }
    }

    public void switchWakeLock(boolean on) {
        if (on) {
            if (mLock == null) {
                mLockToCreate = true;
            }
        } else {
            if (mLock != null) {
                synchronized (this) {
                    if (mLock != null) {
                        mLock.release();
                        mLock = null;
                    }
                }
            }
        }
    }

    public void acquireWakeLock(String tag) {
        acquireWakeLock(tag, -1);
    }

    public void acquireWakeLock(String tag, long timeout) {
        if (mContext != null) {
            if (locks.containsKey(tag) && locks.get(tag) != null) {
                 if (locks.get(tag).isHeld()) {
                     LogUtils.i("WakeLockUtils acquireWakeLock: " + tag + " size:" + locks.size());
                     return;
                 } else {
                     locks.remove(tag);
                 }
            }
            PowerManager.WakeLock wakeLock = ((PowerManager) mContext.getSystemService(Context.POWER_SERVICE))
                    .newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, tag);
            if (timeout > 0)
                wakeLock.acquire(timeout);
            else
                wakeLock.acquire();

            locks.put(tag, wakeLock);
            LogUtils.d("WakeLockUtils acquireWakeLock: " + tag + " size:" + locks.size());
        } else {
            LogUtils.d("WakeLockUtils not init with context");
        }
    }

    public void releaseWakeLock(PowerManager.WakeLock wakeLock) {
        if (wakeLock != null && wakeLock.isHeld()) {
            wakeLock.release();
            wakeLock = null;
        }
    }

    public void releaseWakeLock(String wakeLockTag) {
        if (!locks.containsKey(wakeLockTag)) {
            return;
        }
        PowerManager.WakeLock wakeLock = locks.get(wakeLockTag);
        releaseWakeLock(wakeLock);
        locks.remove(wakeLockTag);
        LogUtils.i("WakeLockUtils releaseWakeLock: " + wakeLockTag + " size:" + locks.size());
    }
}